package main

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"go/token"
	"log"
	"os"
)

func main() {
	// 1. 创建文件集（记录代码位置信息）
	fset := token.NewFileSet()

	fmt.Println("------")
	fmt.Println(os.Getwd())

	// 2. 解析代码文件，生成 AST
	file, err := parser.ParseFile(fset, "./grammar/skill/code.go", nil, parser.ParseComments)
	if err != nil {
		log.Fatal(err)
	}

	// 在之前的解析代码后，新增修改逻辑
	ast.Inspect(file, func(node ast.Node) bool {
		if assign, ok := node.(*ast.AssignStmt); ok {
			// 找到赋值语句的表达式（1 + 2 * 3）
			expr, ok := assign.Rhs[0].(*ast.BinaryExpr)
			if !ok {
				return true
			}

			newJ, ok1 := expr.Y.(*ast.BinaryExpr)
			if !ok1 {
				return true
			}

			newExpr1 := &ast.ParenExpr{X: &ast.BinaryExpr{
				X:     expr.X,
				OpPos: expr.OpPos,
				Op:    expr.Op,
				Y:     newJ.X,
			}}

			expr.X = newExpr1
			//expr.OpPos = newJ.OpPos
			expr.Op = newJ.Op
			expr.Y = newJ.Y

			// 给加法运算加括号（把左子节点变成括号表达式）
			//newExpr := &ast.ParenExpr{X: expr.Y} // 给 1+2 加括号
			//expr = newExpr2 // 替换左操作数
		}
		return true
	})

	// 重新打印修改后的代码
	printer.Fprint(os.Stdout, fset, file)

	// 3. 打印 AST 结构（简化版）
	/*	ast.Inspect(file, func(node ast.Node) bool {
		if node == nil {
			return true
		}

		// 只关注函数声明和赋值语句
		switch n := node.(type) {
		case *ast.FuncDecl: // 函数声明节点
			fmt.Printf("函数名: %s\n", n.Name.Name)
		case *ast.AssignStmt: // 赋值语句节点
			fmt.Printf("赋值语句: ")
			printer.Fprint(os.Stdout, fset, n) // 把节点还原成代码
			fmt.Println()
		}
		return true // 继续遍历子节点
	})*/
}
